package cc.shacocloud.mirage.restful.http;

import cc.shacocloud.mirage.restful.HttpRequest;
import cc.shacocloud.mirage.restful.HttpResponse;
import cc.shacocloud.mirage.utils.MethodParameter;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * 策略接口，指定可以在HTTP请求和响应之间进行转换的转换器
 */
public interface HttpMessageConverter<T> {
    
    /**
     * 返回此转换器支持的{@link MediaType}对象的列表
     *
     * @return 支持的媒体类型列表，是不可变的副本
     */
    List<MediaType> getSupportedMediaTypes();
    
    /**
     * 指示此转换器是否可以读取给定的类
     *
     * @param parameter {@link MethodParameter}
     * @param clazz     可读的类
     * @param mediaType 要读取的媒体类型（如果未指定，可以为{@code null}）； 通常是{@code Content-Type}标头的值。
     * @return {@code true}（如果可读）； {@code false}否则
     */
    boolean canRead(MethodParameter parameter, Class<?> clazz, @Nullable MediaType mediaType);
    
    /**
     * 从给定的输入消息中读取给定类型的对象，并将其返回。
     *
     * @return 包裹在 {@link Future} 中的结果对象
     */
    Future<T> read(MethodParameter parameter, Class<? extends T> clazz, HttpRequest request);
    
    /**
     * 指示给定的类是否可以由此转换器编写
     *
     * @param clazz     测试可写性的类
     * @param mediaType 要写入的媒体类型（如果未指定，可以为{@code null}）； 通常是{@code Accept}标头的值。
     * @return {@code true}（如果可读）； {@code false}否则
     */
    boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
    
    
    /**
     * 将给定对象写入给定输出消息
     *
     * @param t           写入输出消息的对象。 该对象的类型必须先前已传递给此接口的{@link #canWrite canWrite}方法，该方法必须返回{@code true}。
     * @param contentType 编写时使用的内容类型。可能为{@code null}，以指示必须使用转换器的默认内容类型。
     *                    如果不是{@code null}，则此媒体类型必须先前已传递给此接口的{@link #canWrite canWrite}方法，
     *                    该方法必须返回了{@code true}。
     * @param response    响应对象
     * @return {@link Future} 解析后的结果
     */
    Future<Buffer> write(T t, @Nullable MediaType contentType, HttpResponse response);
    
    
}
